﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
//using System.Runtime.Remoting;
using zijian666.Converts.Abstractions;

namespace zijian666.Converts.Dynamic;

/// <summary>
/// 基于 <seealso cref="IDictionary" /> 的动态类型
/// </summary>
internal class DynamicDictionary : DynamicObjectBase<IDictionary>, IDictionary
{

    public DynamicDictionary(IDictionary value!!, IConvertSettings convertSettings)
        : base(value, convertSettings)
    {
    }

    public override bool IsReadOnly => Value!.IsReadOnly;

    public override IEnumerable<string> GetDynamicMemberNames()
    {
        foreach (var key in Value!.Keys)
        {
            if (key is string str)
            {
                yield return str;
            }
        }
    }

    public override bool TryConvert(ConvertBinder binder, out object? result)
    {
        if (Value!.Count == 1)
        {
            foreach (var item in Value.Values)
            {
                if (TryChangeType(item, binder.ReturnType, out result))
                {
                    return true;
                }
                break;
            }
        }
        return TryChangeType(Value, binder.ReturnType, out result);
    }

    protected override object? this[object key]
    {
        get => Value![key];
        set => Value![key] = value;
    }

    #region 显示实现接口

    IEnumerator IEnumerable.GetEnumerator() => Value!.GetEnumerator();
    void IDictionary.Add(object key, object value) => Value!.Add(key, value);
    void IDictionary.Clear() => Value!.Clear();
    bool IDictionary.Contains(object key) => Value!.Contains(key);
    IDictionaryEnumerator IDictionary.GetEnumerator() => Value!.GetEnumerator();
    bool IDictionary.IsFixedSize => false;
    bool IDictionary.IsReadOnly => false;
    ICollection IDictionary.Keys => Value!.Keys;
    void IDictionary.Remove(object key) => Value!.Remove(key);
    ICollection IDictionary.Values => Value!.Values;

    object? IDictionary.this[object key]
    {
        get => Value![key];
        set => Value![key] = value;
    }

    void ICollection.CopyTo(Array array, int index) => Value!.CopyTo(array, index);
    int ICollection.Count => Value!.Count;
    bool ICollection.IsSynchronized { get; } = false;
    object ICollection.SyncRoot => Value!;

    #endregion
}
